package com.jiaozi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jiaozi.base.enums.sys.StateEnum;
import com.jiaozi.core.security.utils.SecurityUtil;
import com.jiaozi.base.utils.bean.R;
import com.jiaozi.system.enums.DepartmentTreePowerEnum;
import com.jiaozi.system.mapper.SysDepartmentMapper;
import com.jiaozi.system.entity.SysDepartment;
import com.jiaozi.system.pojo.param.sys.department.DepartmentSaveUpdateParam;
import com.jiaozi.system.pojo.param.sys.department.DepartmentTreeParam;
import com.jiaozi.system.pojo.vo.sys.department.DepartmentInfoVO;
import com.jiaozi.system.pojo.vo.sys.department.DepartmentTreeVO;
import com.jiaozi.system.service.SysDepartmentService;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统-部门(SysDepartment)表服务实现类
 *
 * @author jiaozi
 * @since 2024-08-15 14:02:36
 */
@Service("sysDepartmentService")
public class SysDepartmentServiceImpl extends MPJBaseServiceImpl<SysDepartmentMapper, SysDepartment> implements SysDepartmentService {

    @Override
    public R<List<DepartmentTreeVO>> departmentListVOR(DepartmentTreeParam departmentTreeParam) {
        //查询集合
        MPJLambdaWrapper<SysDepartment> mpjLambdaWrapper=new MPJLambdaWrapper<>();
        mpjLambdaWrapper.selectAs(SysDepartment::getId, DepartmentTreeVO::getId);
        mpjLambdaWrapper.selectAs(SysDepartment::getPId, DepartmentTreeVO::getPId);
        mpjLambdaWrapper.selectAs(SysDepartment::getDepartmentName, DepartmentTreeVO::getDepartmentName);
        mpjLambdaWrapper.selectAs(SysDepartment::getDepartmentSort, DepartmentTreeVO::getDepartmentSort);
        mpjLambdaWrapper.selectAs(SysDepartment::getDepartmentState, DepartmentTreeVO::getDepartmentState);
        mpjLambdaWrapper.eq(departmentTreeParam.getDepartmentState()!=null, SysDepartment::getDepartmentState,departmentTreeParam.getDepartmentState());
        mpjLambdaWrapper.orderByAsc(SysDepartment::getDepartmentSort);
        //查询全部部门
        List<DepartmentTreeVO> departmentTreeVOS =this.selectJoinList(DepartmentTreeVO.class,mpjLambdaWrapper);

        List<DepartmentTreeVO>  fatherList= null;
        //如果查询类型为空或者查询本部及子部门时
        if(departmentTreeParam.getDepartmentTreePowerEnum()==null||departmentTreeParam.getDepartmentTreePowerEnum()== DepartmentTreePowerEnum.THIS_CHILD_DEPARTMENT){
            fatherList= departmentTreeVOS.stream().filter(e->e.getId().equals(SecurityUtil.getLoginUser().getDepartment().getDepartmentId())).collect(Collectors.toList());
        }else if(departmentTreeParam.getDepartmentTreePowerEnum()== DepartmentTreePowerEnum.ALL){
            //查询全部部门
            fatherList=  departmentTreeVOS.stream().filter(e->e.getPId().equals("0")).collect(Collectors.toList());
        }

        //循环递归子部门
        for (DepartmentTreeVO departmentTreeVO : fatherList) {
            findChild( departmentTreeVO,  departmentTreeVOS);
        }

        return R.ok(fatherList);
    }

    @Override
    public R<DepartmentInfoVO> departmentInfo(String departmentId) {
        DepartmentInfoVO departmentInfoVO =BeanUtil.copyProperties(this.getById(departmentId),DepartmentInfoVO.class);
        MPJLambdaWrapper<SysDepartment> mpjLambdaWrapper=new MPJLambdaWrapper<>();
        mpjLambdaWrapper.eq(SysDepartment::getPId,departmentId);
        if(this.count(mpjLambdaWrapper)>0){
            departmentInfoVO.setChildExist(true);
        }else{
            departmentInfoVO.setChildExist(false);
        }
        return R.ok(departmentInfoVO);
    }


    @Override
    public R departmentSave(DepartmentSaveUpdateParam departmentSaveUpdateParam) {
        SysDepartment sysDepartment=this.getById(departmentSaveUpdateParam.getPId());
        departmentSaveUpdateParam.setDepartmentState(sysDepartment.getDepartmentState());
        this.save(BeanUtil.copyProperties(departmentSaveUpdateParam, SysDepartment.class));
        return R.ok();
    }

    @Override
    public R departmentUpdate(String departmentId, DepartmentSaveUpdateParam departmentSaveUpdateParam) {
        SysDepartment  sysDepartment=BeanUtil.copyProperties(departmentSaveUpdateParam, SysDepartment.class);
        SysDepartment sysDepartmentLow=this.getById(departmentId);
        //判断上级部门发生变化
        if(!sysDepartmentLow.getPId().toString().equals(departmentSaveUpdateParam.getPId())){
            //新的上级部门是停用状态
            if(this.getById(sysDepartment.getPId()).getDepartmentState()==StateEnum.STOP){
                //变更本级和子集为停用状态
                LambdaUpdateWrapper<SysDepartment> sysDepartmentLambdaUpdateWrapper=new LambdaUpdateWrapper<>();
                sysDepartmentLambdaUpdateWrapper.set(SysDepartment::getDepartmentState,StateEnum.STOP);
                sysDepartmentLambdaUpdateWrapper.in(SysDepartment::getId,departmentIdList(departmentId));
                this.update(sysDepartmentLambdaUpdateWrapper);
            }
        }
        sysDepartment.setId(Long.parseLong(departmentId));
        this.updateById(sysDepartment);
        return R.ok();
    }

    @Override
    public R updatyeDepartmentState(String departmentId) {
        SysDepartment sysDepartmentLow=this.getById(departmentId);
        LambdaUpdateWrapper<SysDepartment> sysDepartmentLambdaUpdateWrapper=new LambdaUpdateWrapper<>();
        //当前状态为启用，改为停用，包含子部门
        if(sysDepartmentLow.getDepartmentState()==StateEnum.NORMAL){
            sysDepartmentLambdaUpdateWrapper.set(SysDepartment::getDepartmentState,StateEnum.STOP);
            sysDepartmentLambdaUpdateWrapper.in(SysDepartment::getId,departmentIdList(departmentId));
        }else{
            //当前状态停用，改为启用不包含子部门
            sysDepartmentLambdaUpdateWrapper.set(SysDepartment::getDepartmentState,StateEnum.NORMAL);
            sysDepartmentLambdaUpdateWrapper.eq(SysDepartment::getId,departmentId);
        }
        this.update(sysDepartmentLambdaUpdateWrapper);

        return R.ok();
    }

    @Override
    public List<String> departmentIdList(String departmentId) {


        MPJLambdaWrapper<SysDepartment> mpjLambdaWrapper=new MPJLambdaWrapper<>();
        mpjLambdaWrapper.selectAs(SysDepartment::getId, DepartmentTreeVO::getId);
        mpjLambdaWrapper.selectAs(SysDepartment::getPId, DepartmentTreeVO::getPId);
        mpjLambdaWrapper.eq(SysDepartment::getDepartmentState, StateEnum.NORMAL);
        mpjLambdaWrapper.orderByAsc(SysDepartment::getDepartmentSort);
        List<DepartmentTreeVO> departmentTreeVOS =this.selectJoinList(DepartmentTreeVO.class,mpjLambdaWrapper);
        List<DepartmentTreeVO>  fatherList= null;

        if(StrUtil.isBlank(departmentId)){
            fatherList=  departmentTreeVOS.stream().filter(e->e.getPId().equals("0")).collect(Collectors.toList());
        }else {
            fatherList= departmentTreeVOS.stream().filter(e->e.getId().equals(departmentId)).collect(Collectors.toList());
        }
        List<String> ids=new ArrayList<>();
        for (DepartmentTreeVO departmentTreeVO : fatherList) {
            departmentIdList(ids, departmentTreeVO, departmentTreeVOS);
        }
        return ids;
    }


    /**
     * 根据本部门递归子部门 获取id
     * @param ids
     * @param departmentTreeVO
     * @param departmentTreeVOS
     * @return
     */
    public List<String>departmentIdList(List<String> ids,DepartmentTreeVO departmentTreeVO, List<DepartmentTreeVO> departmentTreeVOS) {
        ids.add(departmentTreeVO.getId());
        List<DepartmentTreeVO>  list= departmentTreeVOS.stream().filter(e->e.getPId().equals(departmentTreeVO.getId())).collect(Collectors.toList());
        if(list!=null&&list.size()>0){
            for (DepartmentTreeVO listVO : list) {
                departmentIdList( ids,listVO, departmentTreeVOS);
            }

        }
        return ids;
    }

    /**
     * 根据本部门递归子部门
     * @param departmentTreeVO
     * @param departmentTreeVOS
     * @return
     */
    private DepartmentTreeVO findChild(DepartmentTreeVO departmentTreeVO, List<DepartmentTreeVO> departmentTreeVOS){
        List<DepartmentTreeVO>  list= departmentTreeVOS.stream().filter(e->e.getPId().equals(departmentTreeVO.getId())).collect(Collectors.toList());
        if(list!=null&&list.size()>0){
            departmentTreeVO.setChildDepartmentList(list);
            for (DepartmentTreeVO listVO : departmentTreeVO.getChildDepartmentList()) {
                findChild( listVO, departmentTreeVOS);
            }
        }
        return departmentTreeVO;
    }




}

